#include "PolynomialPack.h"

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::log(double x)
{
	return System::Math::Log(x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::exp(double x)
{
	return System::Math::Exp(x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::sqrt(double x)
{
	return System::Math::Sqrt(x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::atan(double x)
{
	return System::Math::Atan(x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::pow_dd(double x, double y)
{
	return System::Math::Pow(x, y);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::pow_dd(doublereal *ap,
																			   doublereal *bp)
{
	return System::Math::Pow(*ap,  *bp);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::d_sign(doublereal *a,
																			   doublereal *b)
{
	double x;
	x = (*a >= 0 ?  *a:  -  *a);
	return (*b >= 0 ? x :  - x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::r_sign(real *a, real *b)
{
	double x;
	x = (*a >= 0 ?  *a:  -  *a);
	return (*b >= 0 ? x :  - x);
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::pow_ri(real *ap, integer *bp)
{
	double pow, x;
	integer n;
	unsigned long u;

	pow = 1;
	x = *ap;
	n = *bp;

	if(n != 0)
	{
		if(n < 0)
		{
			n = -n;
			x = 1/x;
		}
		for(u = n; ; )
		{
			if(u & 01)
				pow *= x;
			if(u >>= 1)
				x *= x;
			else
				break;
		}
	}
	return(pow);
}

void SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
{
	register char *aend, *bend;

	aend = a + la;

	if(la <= lb)
		if (a <= b || a >= b + la)
			while(a < aend)
				*a++ = *b++;
		else
			for(b += la; a < aend; )
				*--aend = *--b;
	else {
		bend = b + lb;
		if (a <= b || a >= bend)
			while(b < bend)
				*a++ = *b++;
		else {
			a += lb;
			while(b < bend)
				*--a = *--bend;
			a += lb;
		}
		while(a < aend)
			*a++ = ' ';
	}
}

double SmartMathLibrary::PolynomialPack::ManagedPolynomialPackProvider::pow_di(doublereal *ap, integer *bp)
{
	double pow, x;
	integer n;
	unsigned long u;

	pow = 1;
	x = *ap;
	n = *bp;

	if(n != 0)
	{
		if(n < 0)
		{
			n = -n;
			x = 1/x;
		}
		for(u = n; ; )
		{
			if(u & 01)
				pow *= x;
			if(u >>= 1)
				x *= x;
			else
				break;
		}
	}
	return(pow);
}